Home:ALL Converter>Where should I put my property without violating the MVVM pattern?

Where should I put my property without violating the MVVM pattern?

Ask Time:2020-02-24T01:07:30         Author:Matthias Güntert

Json Formatter

I am new to Xamarin and the MVVM pattern and I have a simple application that should display contacts in a list.

Now my view displays the contacts lastname and its number. Okay, great! Now I would like to have Lastname and Surname displayed. Sure I could modify my model to hold a property of something called public string FullName and fill that. But I guess thats not in the spirit of the pattern, right?

Where should I reflect something like this without violating the pattern? Only within view and the XAML file by using something like <MultiBinding />? Or should my ViewModel hold additional properties?

This is my code:

Model:

public class Contact
{
    public string Id { get; set; }

    public string Surname { get; set; }

    public string Lastname { get; set; }

    public string Number { get; set; }
}

ViewModel:

public class ContactsViewModel : ViewModelBase
{
    public ObservableCollection<Contact> Contacts { get; set; }

    public Command LoadContacts { get; set; } 

    public ContactsViewModel()
    {
        this.Title = "List of contacts";
        Contacts = new ObservableCollection<Contact>();
        LoadContacts = new Command(async () => await LoadContactsFromDataStore());
    }

    private async Task LoadContactsFromDataStore()
    {
        var contacts = await ContactDataStore.GetItemsAsync(true);

        foreach (var contact in contacts)
        {
            Contacts.Add(contact);
        }
    }
}

And my base class

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public string Title { get; set; }

    public IContactDataStore<Contact> ContactDataStore => DependencyService.Get<IContactDataStore<Contact>>();

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

View:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="New Contact" Clicked="AddContact_Clicked"/>
</ContentPage.ToolbarItems>

<StackLayout>
    <ListView x:Name="ContactsListView"
              ItemsSource="{Binding Contacts}"
              VerticalOptions="FillAndExpand"
              HasUnevenRows="True"
              ItemSelected="OnItemSelected">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="10">
                        <Label Text="{Binding Lastname}" FontSize="16"></Label>
                        <Label Text="{Binding Number}" FontSize="13"></Label>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>            
</StackLayout>

Code behind:

[DesignTimeVisible(false)]
public partial class ContactsPage : ContentPage
{
    private readonly ContactsViewModel contactsViewModel;

    public ContactsPage()
    {
        InitializeComponent();

        BindingContext = contactsViewModel = new ContactsViewModel();
    }

    private async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
    {
        if (!(args.SelectedItem is Contact contact))
            return;

        await Navigation.PushAsync(new ContactDetailPage(new ContactDetailViewModel(contact)));

        ContactsListView.SelectedItem = null;
    }

    private async void AddContact_Clicked(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (contactsViewModel.Contacts.Count == 0)
        {
            contactsViewModel.LoadContacts.Execute(null);
        }
    }
}

Author:Matthias Güntert,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/60364695/where-should-i-put-my-property-without-violating-the-mvvm-pattern
yy